﻿#include "CharacterInfo.h"
#include "../../Shared/ServerPackets.h"

using namespace Server::MirEnvir;
using namespace Server::MirNetwork;
using namespace Server::MirObjects;

namespace Server::MirDatabase
{

    Server::MirEnvir::Envir *CharacterInfo::getEnvir()
    {
        return Envir::getMain();
    }

    CharacterInfo::CharacterInfo()
    {
    }

    CharacterInfo::CharacterInfo(ClientPackets::NewCharacter *p, MirConnection *c)
    {
        Name = p->Name;
        Class = p->Class;
        Gender = p->Gender;

        CreationIP = c->IPAddress;
        CreationDate = getEnvir()->getNow();
    }

    CharacterInfo::CharacterInfo(BinaryReader *reader)
    {
        Index = reader->ReadInt32();
        Name = reader->ReadString();

        if (Envir::LoadVersion < 62)
        {
            Level = static_cast<unsigned short>(reader->ReadByte());
        }
        else
        {
            Level = reader->ReadUInt16();
        }

        Class = static_cast<MirClass>(reader->ReadByte());
        Gender = static_cast<MirGender>(reader->ReadByte());
        Hair = reader->ReadByte();

        CreationIP = reader->ReadString();
        CreationDate = DateTime::FromBinary(reader->ReadInt64());

        Banned = reader->ReadBoolean();
        BanReason = reader->ReadString();
        ExpiryDate = DateTime::FromBinary(reader->ReadInt64());

        LastIP = reader->ReadString();
        LastLogoutDate = DateTime::FromBinary(reader->ReadInt64());

        if (Envir::LoadVersion > 81)
        {
            LastLoginDate = DateTime::FromBinary(reader->ReadInt64());
        }

        Deleted = reader->ReadBoolean();
        DeleteDate = DateTime::FromBinary(reader->ReadInt64());

        CurrentMapIndex = reader->ReadInt32();
        CurrentLocation = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        BindMapIndex = reader->ReadInt32();
        BindLocation = new Point(reader->ReadInt32(), reader->ReadInt32());

        if (Envir::LoadVersion <= 84)
        {
            HP = reader->ReadUInt16();
            MP = reader->ReadUInt16();
        }
        else
        {
            HP = reader->ReadInt32();
            MP = reader->ReadInt32();
        }

        Experience = reader->ReadInt64();

        AMode = static_cast<AttackMode>(reader->ReadByte());
        PMode = static_cast<PetMode>(reader->ReadByte());

        if (Envir::LoadVersion > 34)
        {
            PKPoints = reader->ReadInt32();
        }

        int count = reader->ReadInt32();

        Array::Resize(Inventory, count);

        for (int i = 0; i < count; i++)
        {
            if (!reader->ReadBoolean())
            {
                continue;
            }
            UserItem *item = new UserItem(reader, Envir::LoadVersion, Envir::LoadCustomVersion);
            if (getEnvir()->BindItem(item) && i < Inventory.size())
            {
                Inventory[i] = item;
            }

//C# TO C++ CONVERTER TODO TASK: A 'delete item' statement was not added since item was passed to a method or constructor. Handle memory management manually.
        }

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            if (!reader->ReadBoolean())
            {
                continue;
            }
            UserItem *item = new UserItem(reader, Envir::LoadVersion, Envir::LoadCustomVersion);
            if (getEnvir()->BindItem(item) && i < Equipment.size())
            {
                Equipment[i] = item;
            }

//C# TO C++ CONVERTER TODO TASK: A 'delete item' statement was not added since item was passed to a method or constructor. Handle memory management manually.
        }

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            if (!reader->ReadBoolean())
            {
                continue;
            }
            UserItem *item = new UserItem(reader, Envir::LoadVersion, Envir::LoadCustomVersion);
            if (getEnvir()->BindItem(item) && i < QuestInventory.size())
            {
                QuestInventory[i] = item;
            }

//C# TO C++ CONVERTER TODO TASK: A 'delete item' statement was not added since item was passed to a method or constructor. Handle memory management manually.
        }

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            UserMagic *magic = new UserMagic(reader);
            if (magic->Info == nullptr)
            {
                delete magic;
                continue;
            }
            Magics.push_back(magic);

//C# TO C++ CONVERTER TODO TASK: A 'delete magic' statement was not added since magic was passed to a method or constructor. Handle memory management manually.
        }
        //reset all magic cooldowns on char loading < stops ppl from having none working skills after a server crash
        for (int i = 0; i < Magics.size(); i++)
        {
            Magics[i]->CastTime = 0;
        }

        Thrusting = reader->ReadBoolean();
        HalfMoon = reader->ReadBoolean();
        CrossHalfMoon = reader->ReadBoolean();
        DoubleSlash = reader->ReadBoolean();

        MentalState = reader->ReadByte();

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            PetInfo tempVar(reader);
            Pets.push_back(&tempVar);
        }

        AllowGroup = reader->ReadBoolean();

        for (int i = 0; i < Globals::FlagIndexCount; i++)
        {
            Flags[i] = reader->ReadBoolean();
        }

        GuildIndex = reader->ReadInt32();

        AllowTrade = reader->ReadBoolean();

        count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            QuestProgressInfo *quest = new QuestProgressInfo(reader);
            if (getEnvir()->BindQuest(quest))
            {
                CurrentQuests.push_back(quest);
            }

//C# TO C++ CONVERTER TODO TASK: A 'delete quest' statement was not added since quest was passed to a method or constructor. Handle memory management manually.
        }

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            Buff *buff = new Buff(reader);

            Buffs.push_back(buff);

//C# TO C++ CONVERTER TODO TASK: A 'delete buff' statement was not added since buff was passed to a method or constructor. Handle memory management manually.
        }

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            MailInfo tempVar2(reader, Envir::LoadVersion, Envir::LoadCustomVersion);
            Mail.push_back(&tempVar2);
        }

        //IntelligentCreature
        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            UserIntelligentCreature *creature = new UserIntelligentCreature(reader);
            if (creature->Info == nullptr)
            {
                delete creature;
                continue;
            }
            IntelligentCreatures.push_back(creature);

//C# TO C++ CONVERTER TODO TASK: A 'delete creature' statement was not added since creature was passed to a method or constructor. Handle memory management manually.
        }

        if (Envir::LoadVersion == 45)
        {
            auto old1 = static_cast<IntelligentCreatureType>(reader->ReadByte());
            auto old2 = reader->ReadBoolean();
        }

        PearlCount = reader->ReadInt32();

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            CompletedQuests.push_back(reader->ReadInt32());
        }

        if (reader->ReadBoolean())
        {
            CurrentRefine = new UserItem(reader, Envir::LoadVersion, Envir::LoadCustomVersion);
        }
        if (CurrentRefine != nullptr)
        {
            getEnvir()->BindItem(CurrentRefine);
        }

        CollectTime = reader->ReadInt64();
        CollectTime += getEnvir()->getTime();

        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            FriendInfo tempVar3(reader);
            Friends.push_back(&tempVar3);
        }

        if (Envir::LoadVersion > 75)
        {
            count = reader->ReadInt32();
            for (auto i = 0; i < count; i++)
            {
                ItemRentalInformation tempVar4(reader);
                RentedItems.push_back(&tempVar4);
            }

            HasRentedItem = reader->ReadBoolean();
        }

        Married = reader->ReadInt32();
        MarriedDate = DateTime::FromBinary(reader->ReadInt64());
        Mentor = reader->ReadInt32();
        MentorDate = DateTime::FromBinary(reader->ReadInt64());
        isMentor = reader->ReadBoolean();
        MentorExp = reader->ReadInt64();

        if (Envir::LoadVersion >= 63)
        {
            int logCount = reader->ReadInt32();

            for (int i = 0; i < logCount; i++)
            {
                GSpurchases.emplace(reader->ReadInt32(), reader->ReadInt32());
            }
        }
    }

    void CharacterInfo::Save(BinaryWriter *writer)
    {
        writer->Write(Index);
        writer->Write(Name);
        writer->Write(Level);
        writer->Write(static_cast<unsigned char>(Class));
        writer->Write(static_cast<unsigned char>(Gender));
        writer->Write(Hair);

        writer->Write(CreationIP);
        writer->Write(CreationDate.ToBinary());

        writer->Write(Banned);
        writer->Write(BanReason);
        writer->Write(ExpiryDate.ToBinary());

        writer->Write(LastIP);
        writer->Write(LastLogoutDate.ToBinary());
        writer->Write(LastLoginDate.ToBinary());

        writer->Write(Deleted);
        writer->Write(DeleteDate.ToBinary());

        writer->Write(CurrentMapIndex);
        writer->Write(CurrentLocation->X);
        writer->Write(CurrentLocation->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(BindMapIndex);
        writer->Write(BindLocation->X);
        writer->Write(BindLocation->Y);

        writer->Write(HP);
        writer->Write(MP);
        writer->Write(Experience);

        writer->Write(static_cast<unsigned char>(AMode));
        writer->Write(static_cast<unsigned char>(PMode));

        writer->Write(PKPoints);

        writer->Write(Inventory.size());
        for (int i = 0; i < Inventory.size(); i++)
        {
            writer->Write(Inventory[i] != nullptr);
            if (Inventory[i] == nullptr)
            {
                continue;
            }

            Inventory[i]->Save(writer);
        }

        writer->Write(Equipment.size());
        for (int i = 0; i < Equipment.size(); i++)
        {
            writer->Write(Equipment[i] != nullptr);
            if (Equipment[i] == nullptr)
            {
                continue;
            }

            Equipment[i]->Save(writer);
        }

        writer->Write(QuestInventory.size());
        for (int i = 0; i < QuestInventory.size(); i++)
        {
            writer->Write(QuestInventory[i] != nullptr);
            if (QuestInventory[i] == nullptr)
            {
                continue;
            }

            QuestInventory[i]->Save(writer);
        }

        writer->Write(Magics.size());
        for (int i = 0; i < Magics.size(); i++)
        {
            Magics[i]->Save(writer);
        }

        writer->Write(Thrusting);
        writer->Write(HalfMoon);
        writer->Write(CrossHalfMoon);
        writer->Write(DoubleSlash);
        writer->Write(MentalState);

        writer->Write(Pets.size());
        for (int i = 0; i < Pets.size(); i++)
        {
            Pets[i]->Save(writer);
        }

        writer->Write(AllowGroup);

        for (int i = 0; i < Flags.size(); i++)
        {
            writer->Write(Flags[i]);
        }
        writer->Write(GuildIndex);

        writer->Write(AllowTrade);

        writer->Write(CurrentQuests.size());
        for (int i = 0; i < CurrentQuests.size(); i++)
        {
            CurrentQuests[i]->Save(writer);
        }

        writer->Write(Buffs.size());
        for (int i = 0; i < Buffs.size(); i++)
        {
            Buffs[i]->Save(writer);
        }

        writer->Write(Mail.size());
        for (int i = 0; i < Mail.size(); i++)
        {
            Mail[i]->Save(writer);
        }

        //IntelligentCreature
        writer->Write(IntelligentCreatures.size());
        for (int i = 0; i < IntelligentCreatures.size(); i++)
        {
            IntelligentCreatures[i]->Save(writer);
        }
        writer->Write(PearlCount);

        writer->Write(CompletedQuests.size());
        for (int i = 0; i < CompletedQuests.size(); i++)
        {
            writer->Write(CompletedQuests[i]);
        }


        writer->Write(CurrentRefine != nullptr);
        if (CurrentRefine != nullptr)
        {
            CurrentRefine->Save(writer);
        }

        if ((CollectTime - getEnvir()->getTime()) < 0)
        {
            CollectTime = 0;
        }
        else
        {
            CollectTime -= getEnvir()->getTime();
        }

        writer->Write(CollectTime);

        writer->Write(Friends.size());
        for (int i = 0; i < Friends.size(); i++)
        {
            if (Friends[i]->getInfo() == nullptr)
            {
                continue;
            }
            Friends[i]->Save(writer);
        }

        writer->Write(RentedItems.size());
        for (auto rentedItemInformation : RentedItems)
        {
            rentedItemInformation->Save(writer);
        }

        writer->Write(HasRentedItem);

        writer->Write(Married);
        writer->Write(MarriedDate.ToBinary());
        writer->Write(Mentor);
        writer->Write(MentorDate.ToBinary());
        writer->Write(isMentor);
        writer->Write(MentorExp);

        writer->Write(GSpurchases.size());

        for (auto item : GSpurchases)
        {
            writer->Write(item.Key);
            writer->Write(item.Value);
        }
    }

    SelectInfo *CharacterInfo::ToSelectInfo()
    {
        SelectInfo *tempVar = new SelectInfo();
        tempVar->Index = Index;
        tempVar->Name = Name;
        tempVar->Level = Level;
        tempVar->Class = Class;
        tempVar->Gender = Gender;
        tempVar->LastAccess = LastLogoutDate;

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was used in a 'return' or 'throw' statement.
        return tempVar;
    }

    bool CharacterInfo::CheckHasIntelligentCreature(IntelligentCreatureType petType)
    {
        for (int i = 0; i < IntelligentCreatures.size(); i++)
        {
            if (IntelligentCreatures[i]->PetType == petType)
            {
                return true;
            }
        }
        return false;
    }

    int CharacterInfo::ResizeInventory()
    {
        if (Inventory.size() >= 86)
        {
            return Inventory.size();
        }

        if (Inventory.size() == 46)
        {
            Array::Resize(Inventory, Inventory.size() + 8);
        }
        else
        {
            Array::Resize(Inventory, Inventory.size() + 4);
        }

        return Inventory.size();
    }

    PetInfo::PetInfo(MonsterObject *ob)
    {
        MonsterIndex = ob->Info->Index;
        HP = ob->HP;
        Experience = ob->PetExperience;
        Level = ob->PetLevel;
        MaxPetLevel = ob->MaxPetLevel;
    }

    PetInfo::PetInfo(BinaryReader *reader)
    {
        MonsterIndex = reader->ReadInt32();
        if (MonsterIndex == 271)
        {
            MonsterIndex = 275;
        }

        if (Envir::LoadVersion <= 84)
        {
            HP = static_cast<int>(reader->ReadUInt32());
        }
        else
        {
            HP = reader->ReadInt32();
        }

        Experience = reader->ReadUInt32();
        Level = reader->ReadByte();
        MaxPetLevel = reader->ReadByte();
    }

    void PetInfo::Save(BinaryWriter *writer)
    {
        writer->Write(MonsterIndex);
        writer->Write(HP);
        writer->Write(Experience);
        writer->Write(Level);
        writer->Write(MaxPetLevel);
    }

    bool MountInfo::getCanRide() const
    {
        return getHasMount() && getSlots()[static_cast<int>(MountSlot::Saddle)] != nullptr;
    }

    bool MountInfo::getCanMapRide() const
    {
        return getHasMount() && !Player->getCurrentMap()->Info->NoMount;
    }

    bool MountInfo::getCanDungeonRide() const
    {
        return getHasMount() && getCanMapRide() && (!Player->getCurrentMap()->Info->NeedBridle || getSlots()[static_cast<int>(MountSlot::Reins)] != nullptr);
    }

    bool MountInfo::getCanAttack() const
    {
        return getHasMount() && getSlots()[static_cast<int>(MountSlot::Bells)] != nullptr || !getRidingMount();
    }

    bool MountInfo::getSlowLoyalty() const
    {
        return getHasMount() && getSlots()[static_cast<int>(MountSlot::Ribbon)] != nullptr;
    }

    bool MountInfo::getHasMount() const
    {
        return Player->Info->Equipment[static_cast<int>(EquipmentSlot::Mount)] != nullptr;
    }

    bool MountInfo::getRidingMount() const
    {
        return Player->RidingMount;
    }

    void MountInfo::setRidingMount(bool value)
    {
        Player->RidingMount = value;
    }

    std::vector<UserItem*> MountInfo::getSlots() const
    {
        return Player->Info->Equipment[static_cast<int>(EquipmentSlot::Mount)]->Slots;
    }

    MountInfo::MountInfo(PlayerObject *ob)
    {
        Player = ob;
    }

    Server::MirEnvir::Envir *FriendInfo::getEnvir()
    {
        return Envir::getMain();
    }

    CharacterInfo *FriendInfo::getInfo() const
    {
        if (_Info == nullptr)
        {
            _Info = getEnvir()->GetCharacterInfo(Index);
        }

        return _Info;
    }

    FriendInfo::FriendInfo(CharacterInfo *info, bool blocked)
    {
        Index = info->Index;
        Blocked = blocked;
        Memo = "";
    }

    FriendInfo::FriendInfo(BinaryReader *reader)
    {
        Index = reader->ReadInt32();
        Blocked = reader->ReadBoolean();
        Memo = reader->ReadString();
    }

    void FriendInfo::Save(BinaryWriter *writer)
    {
        writer->Write(Index);
        writer->Write(Blocked);
        writer->Write(Memo);
    }

    ClientFriend *FriendInfo::CreateClientFriend()
    {
        ClientFriend *tempVar = new ClientFriend();
        tempVar->Index = Index;
        tempVar->Name = getInfo()->Name;
        tempVar->Blocked = Blocked;
        tempVar->Memo = Memo;
        tempVar->Online = getInfo()->Player != nullptr && getInfo()->Player->Node != nullptr;

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was used in a 'return' or 'throw' statement.
        return tempVar;
    }

std::vector<IntelligentCreatureInfo*> IntelligentCreatureInfo::Creatures;

    IntelligentCreatureInfo::StaticConstructor::StaticConstructor()
    {
         IntelligentCreatureInfo *tempVar = new IntelligentCreatureInfo();
         tempVar->PetType = IntelligentCreatureType::BabyPig;
         tempVar->Icon = 500;
         tempVar->SemiAutoPickupEnabled = true;
         tempVar->SemiAutoPickupRange = 3;
         tempVar->MinimalFullness = 4000;
         IntelligentCreatureInfo *tempVar2 = new IntelligentCreatureInfo();
         tempVar2->PetType = IntelligentCreatureType::Chick;
         tempVar2->Icon = 501;
         tempVar2->MousePickupEnabled = true;
         tempVar2->MousePickupRange = 11;
         tempVar2->AutoPickupEnabled = true;
         tempVar2->AutoPickupRange = 7;
         tempVar2->SemiAutoPickupEnabled = true;
         tempVar2->SemiAutoPickupRange = 7;
         tempVar2->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar3 = new IntelligentCreatureInfo();
         tempVar3->PetType = IntelligentCreatureType::Kitten;
         tempVar3->Icon = 502;
         tempVar3->SemiAutoPickupEnabled = true;
         tempVar3->SemiAutoPickupRange = 3;
         tempVar3->MinimalFullness = 6000;
         IntelligentCreatureInfo *tempVar4 = new IntelligentCreatureInfo();
         tempVar4->PetType = IntelligentCreatureType::BabySkeleton;
         tempVar4->Icon = 503;
         tempVar4->MousePickupEnabled = true;
         tempVar4->MousePickupRange = 11;
         tempVar4->AutoPickupEnabled = true;
         tempVar4->AutoPickupRange = 7;
         tempVar4->SemiAutoPickupEnabled = true;
         tempVar4->SemiAutoPickupRange = 7;
         tempVar4->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar5 = new IntelligentCreatureInfo();
         tempVar5->PetType = IntelligentCreatureType::Baekdon;
         tempVar5->Icon = 504;
         tempVar5->MousePickupEnabled = true;
         tempVar5->MousePickupRange = 11;
         tempVar5->AutoPickupEnabled = true;
         tempVar5->AutoPickupRange = 7;
         tempVar5->SemiAutoPickupEnabled = true;
         tempVar5->SemiAutoPickupRange = 7;
         tempVar5->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar6 = new IntelligentCreatureInfo();
         tempVar6->PetType = IntelligentCreatureType::Wimaen;
         tempVar6->Icon = 505;
         tempVar6->MousePickupEnabled = true;
         tempVar6->MousePickupRange = 7;
         tempVar6->AutoPickupEnabled = true;
         tempVar6->AutoPickupRange = 5;
         tempVar6->SemiAutoPickupEnabled = true;
         tempVar6->SemiAutoPickupRange = 5;
         tempVar6->MinimalFullness = 5000;
         IntelligentCreatureInfo *tempVar7 = new IntelligentCreatureInfo();
         tempVar7->PetType = IntelligentCreatureType::BlackKitten;
         tempVar7->Icon = 506;
         tempVar7->MousePickupEnabled = true;
         tempVar7->MousePickupRange = 7;
         tempVar7->AutoPickupEnabled = true;
         tempVar7->AutoPickupRange = 5;
         tempVar7->SemiAutoPickupEnabled = true;
         tempVar7->SemiAutoPickupRange = 5;
         tempVar7->MinimalFullness = 5000;
         IntelligentCreatureInfo *tempVar8 = new IntelligentCreatureInfo();
         tempVar8->PetType = IntelligentCreatureType::BabyDragon;
         tempVar8->Icon = 507;
         tempVar8->MousePickupEnabled = true;
         tempVar8->MousePickupRange = 7;
         tempVar8->AutoPickupEnabled = true;
         tempVar8->AutoPickupRange = 5;
         tempVar8->SemiAutoPickupEnabled = true;
         tempVar8->SemiAutoPickupRange = 5;
         tempVar8->MinimalFullness = 7000;
         IntelligentCreatureInfo *tempVar9 = new IntelligentCreatureInfo();
         tempVar9->PetType = IntelligentCreatureType::OlympicFlame;
         tempVar9->Icon = 508;
         tempVar9->MousePickupEnabled = true;
         tempVar9->MousePickupRange = 11;
         tempVar9->AutoPickupEnabled = true;
         tempVar9->AutoPickupRange = 11;
         tempVar9->SemiAutoPickupEnabled = true;
         tempVar9->SemiAutoPickupRange = 11;
         tempVar9->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar10 = new IntelligentCreatureInfo();
         tempVar10->PetType = IntelligentCreatureType::BabySnowMan;
         tempVar10->Icon = 509;
         tempVar10->MousePickupEnabled = true;
         tempVar10->MousePickupRange = 11;
         tempVar10->AutoPickupEnabled = true;
         tempVar10->AutoPickupRange = 11;
         tempVar10->SemiAutoPickupEnabled = true;
         tempVar10->SemiAutoPickupRange = 11;
         tempVar10->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar11 = new IntelligentCreatureInfo();
         tempVar11->PetType = IntelligentCreatureType::Frog;
         tempVar11->Icon = 510;
         tempVar11->MousePickupEnabled = true;
         tempVar11->MousePickupRange = 11;
         tempVar11->AutoPickupEnabled = true;
         tempVar11->AutoPickupRange = 11;
         tempVar11->SemiAutoPickupEnabled = true;
         tempVar11->SemiAutoPickupRange = 11;
         tempVar11->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar12 = new IntelligentCreatureInfo();
         tempVar12->PetType = IntelligentCreatureType::BabyMonkey;
         tempVar12->Icon = 511;
         tempVar12->MousePickupEnabled = true;
         tempVar12->MousePickupRange = 11;
         tempVar12->AutoPickupEnabled = true;
         tempVar12->AutoPickupRange = 11;
         tempVar12->SemiAutoPickupEnabled = true;
         tempVar12->SemiAutoPickupRange = 11;
         tempVar12->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar13 = new IntelligentCreatureInfo();
         tempVar13->PetType = IntelligentCreatureType::AngryBird;
         tempVar13->Icon = 512;
         tempVar13->MousePickupEnabled = true;
         tempVar13->MousePickupRange = 11;
         tempVar13->AutoPickupEnabled = true;
         tempVar13->AutoPickupRange = 11;
         tempVar13->SemiAutoPickupEnabled = true;
         tempVar13->SemiAutoPickupRange = 11;
         tempVar13->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar14 = new IntelligentCreatureInfo();
         tempVar14->PetType = IntelligentCreatureType::Foxey;
         tempVar14->Icon = 513;
         tempVar14->MousePickupEnabled = true;
         tempVar14->MousePickupRange = 11;
         tempVar14->AutoPickupEnabled = true;
         tempVar14->AutoPickupRange = 11;
         tempVar14->SemiAutoPickupEnabled = true;
         tempVar14->SemiAutoPickupRange = 11;
         tempVar14->CanProduceBlackStone = true;
         IntelligentCreatureInfo *tempVar15 = new IntelligentCreatureInfo();
         tempVar15->PetType = IntelligentCreatureType::MedicalRat;
         tempVar15->Icon = 514;
         tempVar15->MousePickupEnabled = true;
         tempVar15->MousePickupRange = 11;
         tempVar15->AutoPickupEnabled = true;
         tempVar15->AutoPickupRange = 11;
         tempVar15->SemiAutoPickupEnabled = true;
         tempVar15->SemiAutoPickupRange = 11;
         tempVar15->CanProduceBlackStone = true;

        delete tempVar15;
        delete tempVar14;
        delete tempVar13;
        delete tempVar12;
        delete tempVar11;
        delete tempVar10;
        delete tempVar9;
        delete tempVar8;
        delete tempVar7;
        delete tempVar6;
        delete tempVar5;
        delete tempVar4;
        delete tempVar3;
        delete tempVar2;
        delete tempVar;
    }

IntelligentCreatureInfo::StaticConstructor IntelligentCreatureInfo::staticConstructor;

    IntelligentCreatureInfo::IntelligentCreatureInfo()
    {
        Creatures.push_back(this);
    }

    IntelligentCreatureInfo *IntelligentCreatureInfo::GetCreatureInfo(IntelligentCreatureType petType)
    {
        for (int i = 0; i < Creatures.size(); i++)
        {
            IntelligentCreatureInfo *info = Creatures[i];
            if (info->PetType != petType)
            {
                continue;
            }
            return info;
        }
        return nullptr;
    }

    UserIntelligentCreature::UserIntelligentCreature(IntelligentCreatureType creatureType, int slot, unsigned char effect)
    {
        PetType = creatureType;
        Info = IntelligentCreatureInfo::GetCreatureInfo(PetType);
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
        CustomName = Envir::getMain()->GetMonsterInfo(64, static_cast<unsigned char>(PetType)) == nullptr ? "" : (((Envir::getMain()->GetMonsterInfo(64, static_cast<unsigned char>(PetType))->Name) != "") ? Envir::getMain()->GetMonsterInfo(64, static_cast<unsigned char>(PetType))->Name : PetType.ToString());
        Fullness = 7500; //starts at 75% food
        SlotIndex = slot;

        if (effect > 0)
        {
            Expire = DateTime::Now.AddDays(effect); //effect holds the amount in days
        }
        else
        {
            Expire = DateTime::MinValue; //permanent
        }

        BlackstoneTime = 0;
        MaintainFoodTime = 0;

        Filter = new IntelligentCreatureItemFilter();
    }

    UserIntelligentCreature::UserIntelligentCreature(BinaryReader *reader)
    {
        PetType = static_cast<IntelligentCreatureType>(reader->ReadByte());
        Info = IntelligentCreatureInfo::GetCreatureInfo(PetType);

        CustomName = reader->ReadString();
        Fullness = reader->ReadInt32();
        SlotIndex = reader->ReadInt32();

        auto expireTime = reader->ReadInt64();

        if (expireTime == -9999)
        {
            Expire = DateTime::MinValue;
        }
        else
        {
            Expire = DateTime::Now.AddSeconds(expireTime);
        }

        BlackstoneTime = reader->ReadInt64();

        petMode = static_cast<IntelligentCreaturePickupMode>(reader->ReadByte());

        Filter = new IntelligentCreatureItemFilter(reader);
        if (Envir::LoadVersion > 48)
        {
            Filter->PickupGrade = static_cast<ItemGrade>(reader->ReadByte());

            MaintainFoodTime = reader->ReadInt64(); //maintain food buff
        }
    }

    void UserIntelligentCreature::Save(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(PetType));

        writer->Write(CustomName);
        writer->Write(Fullness);
        writer->Write(SlotIndex);

        if (Expire == DateTime::MinValue)
        {
            writer->Write(static_cast<long long>(-9999));
        }
        else
        {
            writer->Write(static_cast<long long>((Expire - DateTime::Now).TotalSeconds));
        }

        writer->Write(BlackstoneTime);

        writer->Write(static_cast<unsigned char>(petMode));

        Filter->Save(writer);
        writer->Write(static_cast<unsigned char>(Filter->PickupGrade)); //since Envir.Version 49

        writer->Write(MaintainFoodTime); //maintain food buff

    }

    Packet *UserIntelligentCreature::GetInfo()
    {
        ServerPackets::NewIntelligentCreature *tempVar = new ServerPackets::NewIntelligentCreature();
        tempVar->Creature = CreateClientIntelligentCreature();

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was used in a 'return' or 'throw' statement.
        return tempVar;
    }

    ClientIntelligentCreature *UserIntelligentCreature::CreateClientIntelligentCreature()
    {
        ClientIntelligentCreature *tempVar = new ClientIntelligentCreature();
        tempVar->PetType = PetType;
        tempVar->Icon = Info->Icon;
        tempVar->CustomName = CustomName;
        tempVar->Fullness = Fullness;
        tempVar->SlotIndex = SlotIndex;
        tempVar->Expire = Expire;
        tempVar->BlackstoneTime = BlackstoneTime;
        tempVar->MaintainFoodTime = MaintainFoodTime;
        tempVar->petMode = petMode;
        tempVar->CreatureRules = new IntelligentCreatureRules();
        tempVar->CreatureRules->MinimalFullness = Info->MinimalFullness;
        tempVar->CreatureRules->MousePickupEnabled = Info->MousePickupEnabled;
        tempVar->CreatureRules->MousePickupRange = Info->MousePickupRange;
        tempVar->CreatureRules->AutoPickupEnabled = Info->AutoPickupEnabled;
        tempVar->CreatureRules->AutoPickupRange = Info->AutoPickupRange;
        tempVar->CreatureRules->SemiAutoPickupEnabled = Info->SemiAutoPickupEnabled;
        tempVar->CreatureRules->SemiAutoPickupRange = Info->SemiAutoPickupRange;
        tempVar->CreatureRules->CanProduceBlackStone = Info->CanProduceBlackStone;
        tempVar->Filter = Filter;

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was used in a 'return' or 'throw' statement.
        return tempVar;
    }
}
